#include "MapGen.h"
#include <windows.h>
#include "math.h"

MapGen::MapGen()
{
    generateRandomMap();
}

MapGen::~MapGen()
{

}

void MapGen::generateRandomMap()
{
    initMap();
    genFloor();
    genMonster();
    genTreasure();
    optMap();

    m_ini_player_x = 0;
    m_ini_player_y = 0;
    int exit_x = 0;
    int exit_y = 0;
    while(true)
    {
        genExit(exit_x, exit_y);
        genPlayer(m_ini_player_x, m_ini_player_y);
        double distance = std::sqrt((m_ini_player_x - exit_x)*(m_ini_player_x - exit_x) +
                                    (m_ini_player_y - exit_y)*(m_ini_player_y - exit_y));
        if(distance > MINPATH)
        {
            break;
        }
        else
        {
            m_map[m_ini_player_x][m_ini_player_y] = '.';
            m_map[exit_x][exit_y] = '.';
        }
    }
}

void MapGen::initMap()
{
    for(int i = 0; i < ROOM_WIDTH; ++i)
    {
        for(int j = 0; j < ROOM_HEIGHT; ++j)
        {
            m_map[i][j] = '#';
        }
    }
}

void MapGen::genFloor()
{
    int handle_x = ROOM_WIDTH / 2;
    int handle_y = ROOM_HEIGHT / 2;

    int dirchange = 0;
    int dir = 0;

    int step = 0;
    while(step != MOVESTEP)
    {
        m_map[handle_x][handle_y] = '.';


        if(dirchange != rand() % 2)
        {
            dir = rand() % 4;
        }

        switch(dir)
        {
        case 0: handle_x++;
            break;
        case 1: handle_y--;
            break;
        case 2: handle_x--;
            break;
        case 3: handle_y++;
            break;
        }

        if(handle_x >= ROOM_WIDTH - 1)
            handle_x -= 2;
        else if(handle_x <= 0)
            handle_x += 2;
        if(handle_y >= ROOM_HEIGHT - 1)
            handle_y -= 2;
        else if(handle_y <= 0)
            handle_y += 2;

        step++;
        //        printMap(m_map);
        //        cout << endl << "Current Step: " << step << endl;
        //        Sleep(10);
        //        system ("cls");
    }
}

void MapGen::genMonster()
{
    int i = 0;
    while(i < MONSTERNUM)
    {
        int x = rand() % (ROOM_WIDTH - 1);
        int y = rand() % (ROOM_HEIGHT - 1);

        if(m_map[x][y] == '.')
        {
            m_map[x][y] = 'M';
            i++;
        }
    }
}

void MapGen::genExit(int &ex, int &ey)
{
    bool generated = false;
    while(!generated)
    {
        int x = rand() % (ROOM_WIDTH - 1);
        int y = rand() % (ROOM_HEIGHT - 1);

        if(m_map[x][y] == '.')
        {
            m_map[x][y] = '0';
            ex = x;
            ey = y;
            generated = true;
        }
    }
}

void MapGen::genPlayer(int &px, int &py)
{
    bool generated = false;
    while(!generated)
    {
        int x = rand() % (ROOM_WIDTH - 1);
        int y = rand() % (ROOM_HEIGHT - 1);

        if(m_map[x][y] == '.')
        {
            px = x;
            py = y;
            generated = true;
        }
    }
}

void MapGen::genTreasure()
{
    int i = 0;
    while(i < TREASURENUM)
    {
        int x = rand() % (ROOM_WIDTH - 1);
        int y = rand() % (ROOM_HEIGHT - 1);

        if(m_map[x][y] == '.')
        {
            m_map[x][y] = 'T';
            i++;
        }
    }
}

void MapGen::optMap()
{
    for(int i = 1; i < ROOM_WIDTH - 1; ++i)
    {
        for(int j = 1; j < ROOM_HEIGHT - 1; ++j)
        {
            if(m_map[i][j] == '#')
            {
                bool right = m_map[i+1][j] == '.';
                bool left = m_map[i-1][j] == '.';
                bool up = m_map[i][j-1] == '.';
                bool down = m_map[i][j+1] == '.';
                if(right&&left&&up&&down)
                    m_map[i][j] = '.';
            }
        }
    }
}
